﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIObjects.TreeViewInterfaces;
using System.Collections.ObjectModel;
using TreeBuilder.Contracts;
using MvvmTreeView;
using System.Windows.Controls;
using System.Diagnostics;
using AbstraX.ClientInterfaces;
using SL4PopupMenu;
using System.Windows;

namespace TreeBuilder.ViewModels
{
    public class TreeBuilderTreeNodeAdvancedQuery : TreeBuilderTreeNodeBase
    {
        private ITreeNodeAdvancedQuery query;
        private bool allowDrop;

        public TreeBuilderTreeNodeAdvancedQuery(ITreeBuilderService treeBuilderService, ITreeView treeView, ITreeNodeAdvancedQuery query, ITreeNode parent) : base(treeBuilderService, treeView, parent)
        {
            this.query = query;
            this.Tag = query;
            this.allowDrop = true;
        }

        public override ITreeNodeBase InternalNodeObject
        {
            get
            {
                return query;
            }
        }

        public override AbstraX.ClientInterfaces.IBase BaseObject
        {
            get
            {
                return query.BaseObject;
            }

            set
            {
                query.BaseObject = value;
            }
        }

        public override void Expand()
        {
            if (!this.IsChildrenLoaded)
            {
                query.ChildrenLoaded += new TreeBuilder.Contracts.ChildrenLoadedHandler(OnChildrenLoaded);
                query.LoadChildren();
            }

            base.Expand();
        }

        public override string Text
        {
            get
            {
                return query.Text;
            }

            set
            {
                query.Text = value;
            }
        }

        public void AddMemberAsNode(object sender, RoutedEventArgs r)
        {
            var menu = (PopupMenuItem)sender;

            if (query.QueryReturn.Any(a => a.Name == (string)menu.Tag && a is IAttribute))
            {
                var attribute = (IAttribute) query.QueryReturn.Single(a => a.Name == (string)menu.Tag && a is IAttribute);
                var createOperation = treeBuilderService.CreateAttributeNode(query, attribute);

                createOperation.NodeCreated += (parent, e) =>
                {
                    this.Nodes.Add(new TreeBuilderTreeNodeAttributeNode(treeBuilderService, treeView, createOperation.NewNode, this) { ChildOrdinal = this.Nodes.Count });
                    base.Expand();
                };
            }
            else if (query.QueryReturn.Any(a => a.Name == (string)menu.Tag && a is IElement))
            {
                var element = (IElement) query.QueryReturn.Single(a => a.Name == (string)menu.Tag && a is IElement);
                var createOperation = treeBuilderService.CreateElementNode(query, element);

                createOperation.NodeCreated += (parent, e) =>
                {
                    this.Nodes.Add(new TreeBuilderTreeNodeElementNode(treeBuilderService, treeView, createOperation.NewNode, this));
                    base.Expand();
                };
            }
        }
        private List<IContextMenuItem> GetSubMenus()
        {
            List<IContextMenuItem> subMenus = new List<IContextMenuItem>();

            foreach (var baseReturn in query.QueryReturn)
            {
                if (baseReturn is IElement)
                {
                    var element = (IElement)baseReturn;

                    subMenus.Add(new ContextMenuItem(null, element.Name, element.Name, AddMemberAsNode));
                }
                else if (baseReturn is IAttribute)
                {
                    var attribute = (IAttribute)baseReturn;

                    subMenus.Add(new ContextMenuItem(null, attribute.Name, attribute.Name, AddMemberAsNode));
                }
            }

            return subMenus;
        }

        public override ContextMenu ContextMenu
        {
            get
            {
                if (contextMenu == null && query.QueryReturn != null)
                {
                    contextMenu = new ContextMenu
                    {
                        Items = new List<IContextMenuItem>()
                        {
                            new ContextMenuItem
                            {
                                Text = "Add Query Result as Node",
                                Items = GetSubMenus(),
                            }
                        }
                    };
                }

                return contextMenu;
            }

            set
            {
                contextMenu = value;
            }
        }

        public override bool? HasChildren
        {
            get { throw new NotImplementedException(); }
        }

        public override string ID
        {
            get 
            {
                return query.ID;
            }
        }

        public override void LoadChildren()
        {
            query.ChildrenLoaded += new TreeBuilder.Contracts.ChildrenLoadedHandler(OnChildrenLoaded);
            query.LoadChildren();
        }

        public override IEnumerable<ITreeNodeBase> Children
        {
            get 
            {
                return query.Children;
            }
        }

        public override void Remove()
        {
            query.RemovedSuccessfully += (node, e) =>
            {
                this.parent.Nodes.Remove(this);

                var op = treeBuilderService.OrphansExist();

                op.Completed += (sender, e2) =>
                {
                    if (op.Value)
                    {
                        MessageBox.Show("Orphans exist!");
                    }
                };
            };

            query.Remove();
        }

        public override bool AllowDrop
        {
            get
            {
                return allowDrop;
            }
            set
            {
                allowDrop = value;
            }
        }

        public override ITreeNode ShallowClone()
        {
            throw new NotImplementedException();
        }

		public override void OnSelect()
		{
		}
        public override ITreeNode DeepClone()
        {
            throw new NotImplementedException();
        }

        public override bool AllowRename
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override bool HasLayoverImage<T>(out T image)
        {
            return query.HasLayoverImage<T>(out image);
        }

        public override void AddNew(string shortCut)
        {
        }

        public override void DragEnter(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragLeave(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragOver(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragStarting(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e)
        {
        }

        public override void DragCompleted(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e)
        {
        }

        public override void ItemDropped(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e, int insertionIndex)
        {
        }

        public override void GiveFeedback(object sender, UIObjects.DragDropInterfaces.GiveFeedbackEventArgs e)
        {
        }

        public override float ChildOrdinal
        {
            get
            {
                return query.ChildOrdinal;
            }
            set
            {
                query.ChildOrdinal = value;
            }
        }
    }
}
